package com.yunhe.authority.service.authority;

import com.github.stuxuhai.jpinyin.PinyinException;
import com.yunhe.authority.domain.authority.*;
import com.yunhe.authority.domain.base.Area;
import com.yunhe.authority.domain.base.FirmType;
import com.yunhe.common.exception.ArgumentErrorException;
import com.yunhe.common.exception.DatabaseProcessException;
import com.yunhe.common.exception.ObjectNotFoundException;
import com.yunhe.common.exception.UniqueConstraintsException;
import com.yunhe.common.model.DomainList;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/**
 * 单位Service
 * @desc 单位服务类定义
 * @author liuronglei
 */
public interface FirmService {

    /**
     * 新增单位
     * @param firm 单位对象
     *
     */
    @Transactional(rollbackFor = Exception.class, transactionManager = "transactionManager")
    Firm createFirm(Firm firm)
            throws ArgumentErrorException, UniqueConstraintsException, ObjectNotFoundException, PinyinException;

    /**
     * 删除单位
     * @param firmId 单位对象ID
     */
    @Transactional
    void deleteFirm(Long firmId);

    /**
     * 更新单位
     * @param firm 单位对象
     * @param parentId 父单位ID
     */
    @Transactional
    Firm updateFirm(Firm firm, Long parentId)
            throws ArgumentErrorException, UniqueConstraintsException, ObjectNotFoundException;

    /**
     * 更新单位（更新指定字段）
     * @param firmId 单位ID
     * @param parentId 父单位ID
     * @param code 单位代码
     * @param name 单位编号
     * @param title 单位名称
     * @param systemTitle 系统标题
     * @param sn 排序
     * @param logAndLat 经纬度
     * @param activity 是否可用
     * @param root 是否为根节点
     */
    @Transactional
    Firm updateFirm(Long firmId,
                    Long parentId,
                    Long code,
                    String name,
                    String title,
                    String systemTitle,
                    String sn,
                    String logAndLat,
                    Long homePageId,
                    Long firmTypeId,
                    Long areaId,
                    Boolean activity,
                    Boolean root)
            throws ArgumentErrorException, ObjectNotFoundException, UniqueConstraintsException;

    /**
     * 更新单位类型
     * @param id 单位ID
     * @param FirmTypeId 单位类型ID
     */
    void updateFirmTypeById(Long id, Long FirmTypeId) throws ObjectNotFoundException;

    /**
     * 更新首页绑定
     * @param id 单位ID
     * @param homePageId 首页对象ID
     */
    @Transactional
    void updateHomePage(Long id, Long homePageId)
            throws ObjectNotFoundException;

    /**
     * 根据单位ID获得单位
     * @param id 单位ID
     */
    Firm findByFirmId(Long id);

    /**
     * 根据单位编号获得单位
     * @param name 单位编号
     */
    Firm findByName(String name);

    /**
     * 根据单位代码获得单位
     * @param code 单位代码
     */
    Firm findByCode(Long code);

    /**
     * 根据条件获得单位列表
     */
    Iterable<Firm> findFirms();

    /**
     * 单位绑定资源
     * @param firmId 单位ID
     * @param type 资源类型
     * @param resourceId 资源ID
     */
    @Transactional
    void bindResource(Long firmId, String type, Long resourceId);

    /**
     * 解绑菜单
     * @param firmId 单位ID
     * @param resourceId 资源ID
     */
    @Transactional
    void unbindResource(Long firmId, Long resourceId);

    /**
     * 批量更新菜单绑定
     * @param firmId 单位ID
     * @param domainList 资源列表
     */
    @Transactional
    void updateResource(Long firmId, DomainList<ResourceTree> domainList)
            throws DatabaseProcessException;

    /**
     * 根据单位ID获得资源树
     * @param firmId 单位ID
     * @param typeList 类型列表
     */
    Iterable<ResourceTree> findResourceTreeByFirmId(Long firmId, List<String> typeList);

    /**
     * 根据单位ID获得单位代码
     * @param firmId 单位ID
     */
    Long getFirmCodeById(Long firmId) throws ObjectNotFoundException;

    /**
     * 根据单位ID获得单位编号
     * @param firmId 单位ID
     */
    String getFirmNameById(Long firmId) throws ObjectNotFoundException;

    /**
     * 获得有单位关联的地区对象
     */
    Iterable<Area> findFirmAreas();

    /**
     * 根据单位代码获得单位关联的地区对象
     * @param code 单位代码
     */
    Area findAreaByCode(Long code);

    /**
     * 根据单位获取所属地区
     * @param firmId
     * @return
     */
    Iterable<Area> findAreaByFirmId(Long firmId);

    /**
     * 更新单位关联的地区对象
     *  @param areaId 地区ID
     *  @param id 单位ID
     */
    void updateArea(Long id, Long areaId)
        throws ObjectNotFoundException;

    /**
     * 单位绑定菜单
     * @param firmId 单位ID
     * @param menuId 菜单ID
     */
    @Transactional
    void bindMenu(Long firmId, Long menuId)
            throws DatabaseProcessException;

    /**
     * 单位绑定菜单
     * @param firmId 单位ID
     * @param menuId 菜单ID
     */
    @Transactional
    void bindAppMenu(Long firmId, Long menuId)
            throws DatabaseProcessException;

    /**
     * 解绑菜单
     * @param firmId 单位ID
     * @param menuId 菜单ID
     */
    @Transactional
    void unbindMenu(Long firmId, Long menuId);

    /**
     * 批量更新菜单绑定
     * @param firmId 单位ID
     * @param menuIdList 菜单ID列表
     */
    @Transactional
    void updateMenu(Long firmId, List<Long> menuIdList)
            throws DatabaseProcessException;

    /**
     * 根据单位ID获得菜单列表
     * @param firmId 单位ID
     */
    Iterable<Menu> findMenusByFirmId(Long firmId);

    /**
     * 根据单位获得单位类型
     * @param id ID
     */
    FirmType findFirmTypeByFirmId(Long id);

    /**
     * 根据单位类型获得单位
     * @param firmTypeId 单位类型ID
     */
    Iterable<Firm> findFirmsByFirmTypeId(Long firmTypeId);

    /**
     * 获得单位绑定的首页
     * @param id 单位ID
     */
    HomePage findHomePageByFirmId(Long id);

//    Iterable<Dev> getDevsByFirm(Long firmCode);

    /**
     * 根据设备ID查找单位
     * @param devId 设备ID
     */
    Iterable<Firm> findFirmByDevId(Long devId);

    /**
     * 根据电站ID查找所属单位
     * @param stationId 电站ID
     */
    Firm findFirmByStationId(Long stationId);

    /**
     * 绑定单位拥有的电站
     * @param id 单位ID
     * @param stationId 电站ID
     */
    void bindStation(Long id, Long stationId);

    /**
     * 解绑单位拥有的电站
     * @param id 单位ID
     * @param stationId 电站ID
     */
    void unbindStation(Long id, Long stationId);

    /**
     * 批量更新电站绑定
     * @param firmId 单位ID
     * @param domainList 资源列表
     */
    @Transactional
    void updateStation(Long firmId, DomainList<Station> domainList);

    Firm findFirmByDevCode(Long devCode);

    Firm findByStationCode(Long stationCode);

    Iterable<Firm> findAll();

    /**
     * 解除静态数据与单位的绑定
     * @param fsdId
     * @param id
     */
    void unbindFirmStaticData(Long fsdId, Long id);

    /**
     * 静态数据与单位进行绑定
     * @param fsdId
     * @param id
     */
    void bindFirmStaticData(Long fsdId, Long id);

    Iterable<Firm> findByRoleIds(List<Long> roleIds);

    Iterable<Firm> findAllFirms();

    /**
     * 通过系统查询系统下的单位
     * @param code
     * @return
     */
    Iterable<Firm> findBySystem(String code);

    /**
     * 根据指定字段更新电站
     * @param id
     * @return
     * @throws ObjectNotFoundException
     */
    @Transactional(rollbackFor = Exception.class, transactionManager = "transactionManager")
    Firm updateFirm(Long id, Project project) throws ObjectNotFoundException, UniqueConstraintsException, ArgumentErrorException;

    Firm findByStationId(Long stationId);
}
